package com.gagakuai.bpm.mqlistener.camunda.handler;


import com.gagakuai.bpm.common.annotation.BpmBusinessType;
import com.gagakuai.bpm.common.enums.BpmConsumeEnum;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/*
 * @program: mss_server
 * @description: 后置处理器查找实现类
 * @author: houhong
 * @create: 2022-03-14 17:28
 */
@Component
public class BpmConsumeProccor implements BeanPostProcessor, BeanFactoryAware {


    private ConfigurableListableBeanFactory applicationContext;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

        this.applicationContext = (ConfigurableListableBeanFactory) beanFactory;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if (bean instanceof AbstractBpmConsumeHandler) {

            BpmBusinessType annotation = bean.getClass().getAnnotation(BpmBusinessType.class);

            BpmConsumeEnum value = annotation.value();

            if (value.getCode().equals(value.getMaxCode())) {


                Map<String, AbstractBpmConsumeHandler> handlerMap = new HashMap<>();
                for (BpmConsumeEnum temp : BpmConsumeEnum.values()) {
                    AbstractBpmConsumeHandler beanInstacle = getBeansWithAnnotation(applicationContext, AbstractBpmConsumeHandler.class, BpmBusinessType.class, temp.getCode());
                    handlerMap.put(temp.getCode(), beanInstacle);
                }
                BpmConsumeContext context = new BpmConsumeContext(handlerMap);
                //单例注入
                applicationContext.registerSingleton(BpmConsumeContext.class.getName(), context);


            }


        }
        return bean;
    }

    /*
     * 通过父类+注解找到实体类
     */
    private <T> T getBeansWithAnnotation(ConfigurableListableBeanFactory beanFactory, Class<T> manager, Class<? extends BpmBusinessType> annotation, String code) throws BeansException {
        if (ObjectUtils.isEmpty(code)) {
            throw new RuntimeException("code is null ");
        }
        Collection<T> tCollection = beanFactory.getBeansOfType(manager).values();
        for (T t : tCollection) {

            BpmBusinessType mainBoardTaskType = t.getClass().getAnnotation(annotation);
            if (ObjectUtils.isEmpty(mainBoardTaskType)) {
                throw new RuntimeException("该注解没有写入值 :" + code);
            }
            //注解值是否与code相等
            if (code.equals(mainBoardTaskType.value().getCode())) {
                return t;
            }
        }
        throw new RuntimeException("通过code没有找到该注解对应的实体类 :" + code);
    }


}